﻿using System;
using System.Diagnostics;
using System.IO;
using System.Windows.Forms;

namespace svnbox {
    internal class App {

        #region Declerations

        internal static bool IsRunning = false;
        internal static string DateTimeFormat = "dd/MM/yyyy HH:mm:ss";
        internal static string AppPath = System.Windows.Forms.Application.StartupPath + "\\";
        internal static string Location = System.Reflection.Assembly.GetExecutingAssembly().Location;
        internal static string Version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
        internal static string LogPath {
            get {
                if (!Directory.Exists(AppPath + "Logs\\")) Directory.CreateDirectory(AppPath + "Logs\\");
                return AppPath + "Logs\\";
            }
        }

        internal static string LangPath {
            get {
                if (!Directory.Exists(AppPath + "Language\\")) Directory.CreateDirectory(AppPath + "Language\\");
                return AppPath + "Language\\";
            }
        }

        internal static string ProfilsPath {
            get {
                if (!Directory.Exists(AppPath + "Profile\\")) Directory.CreateDirectory(AppPath + "Profile\\");
                return AppPath + "Profile\\";
            }
        }

        internal static string IniLocation = AppPath + "Settings.ini";
        internal static string LogLocation = LogPath + "activity.log";
        internal static string LogExceptionLocation = LogPath + "exception.log";

        internal static Resource Resource = null;
        internal static Profile Profile = null;
        internal static Svn Svn = null;
        internal static Monitor Monitor = null;


        internal static frmMain MainForm = null;
        internal static frmActivity ActivityForm = null;
        internal static frmProfile ProfileForm = null;

        internal static void debug(string s) { Debug.WriteLine("{App} " + s); }

        internal static void Load() {

            Trace.Listeners.Add(new Logger(App.LogLocation));
            Trace.AutoFlush = true;

            Profile = new Profile(); //Get selected or new profile
            Resource = new Resource();
        }

        #endregion

        internal static void OpenProfileForm() {
            if (ProfileForm == null)
                ProfileForm = new frmProfile();
            // dont add || ! ProfileForm.Visible in reality the form will never close / disposed  (look at form closing Hide event )
            try {
                ProfileForm.Show();
            } catch (Exception ex) {
                debug("OpenProfileForm() - " + ex.Message);
            }
        }

        internal static void OpenActivityForm() {
            if (ActivityForm == null) {
                ActivityForm = new frmActivity();
            }
            // dont add || !ActivityForm.Visible in reality the form will never close (look at form closing Hide event )
            ActivityForm.Show();
        }

        delegate void SetTextCallback(string text);

        internal static void Log(string s) {
            if (ActivityForm == null)
                ActivityForm = new frmActivity();
            if (ActivityForm.txtLog.InvokeRequired) {
                SetTextCallback d = new SetTextCallback(Log);
                ActivityForm.txtLog.Invoke(d, new object[] { s });
            } else {
                ActivityForm.txtLog.Text += s + "\r\n";
            }
        }
        internal static void ShowFatalError(string error) {
            string sMessage;
            if (error == "SVN_ERR_RA_UUID_MISMATCH") {
                sMessage = "Repository was changed , you should delete the .svn folder to start with fresh copy (in case do a backup before)";
            } else {
                sMessage = error;
            }
            MainForm.BalloonTipWarning(Resource.Lang("frmMain", error, sMessage));

            Stop();
        }

        internal static void Start() {

            if (Profile.Get("svn", "repository") == "") {
                MainForm.mSettings_Click(null, null);
                return;
            }

            if (Svn != null) {
                Svn.Host = Profile.Get("svn", "repository");
                Svn.User = Profile.Get("svn", "user");
                Svn.Pass = Profile.Get("svn", "password");
                Svn.RootPath = Profile.Get("wc", "path");
                Svn.SetupSvnCommand();
            } else {
                InitSvn();
            }

            if (!Svn.NetworkAvailable) {
                SetNetDisconectIcon();
            } else {
                Svn.CheckAuthentication(Svn.Host, Svn.User, Svn.Pass);
                SetConnectingIcon();
            }

            if (!Directory.Exists(Svn.RootPath)) {
                MessageBox.Show(Resource.Lang("settings", "MonitorPathNotExist", "Monitor path do not exist... !"));
                MainForm.mSettings_Click(null, null);
                return;
            }
        }

        internal static void InitSvn() {
            Svn = new Svn();

            //Setups the events handlers

            Svn.OnNetworkStatusChange += delegate {
                if (!Svn.NetworkAvailable) {
                    SetNetDisconectIcon();
                } else {
                    Start();
                }
            };

            Svn.OnSyncStatusChange += delegate(object obj, SyncStatusArgs myArgs) {
                string sText = "";
                if (myArgs.REPO_version == myArgs.WC_version) {
                    sText = Resource.Lang("frmMain", "mStatus_updated", "Folder up to date");
                } else {
                    sText = Resource.Lang("frmMain", "mStatus_outdate", "Folder out of date");
                }
                MainForm.MenuItemStatus.Text = sText;
                MainForm.TrayIcon.Text = "Svnbox " + Version + "\n" + sText;

                //IcoOverlay.Change();
            };

            Svn.OnAuthStatusChange += delegate {
                if (Svn.IsAuthentication) {

                    ////////////////////
                    Svn.Start();
                    ///////////////////

                    if (Monitor != null) {
                        Monitor.Stop();
                        Monitor = null;
                    }
                    Monitor = new Monitor(Svn);
                    Monitor.Start();

                    IsRunning = true;

                    //IcoOverlay.Load();

                    SetStopIcon();
                } else {
                    Stop();
                }
            };
        }

        internal static void Stop() {
            if (Monitor != null)
                Monitor.Stop();
            if (Svn != null)
                Svn.Stop();
            IsRunning = false;
            SetStartIcon();
        }

        internal static void SetConnectingIcon() {
            MainForm.SetTrayIcon(2);
            MainForm.MenuItemMonitor.Enabled = false;
            MainForm.MenuItemStatus.Text = Resource.Lang("frmMain", "mStatus_connect", "Connecting..");
        }

        internal static void SetNetDisconectIcon() {
            MainForm.SetTrayIcon(3);
            MainForm.MenuItemStatus.Text = Resource.Lang("frmMain", "mStatus_stop", "Disconnected..");
            MainForm.MenuItemMonitor.Enabled = false;
            MainForm.BalloonTipWarning(Resource.Lang("frmMain", "MessageNetworkDissconected", "Network disconnected.."));
        }

        internal static void SetStartIcon() {
            MainForm.SetTrayIcon(3);
            MainForm.MenuItemMonitor.Text = Resource.Lang("frmMain", "mStartMonitoring_Start", "Start monitoring");
            MainForm.MenuItemStatus.Text = Resource.Lang("frmMain", "mStatus_stop", "Disconnected..");
            MainForm.MenuItemMonitor.Enabled = true;
        }

        internal static void SetStopIcon() {
            MainForm.SetTrayIcon(1);
            MainForm.MenuItemMonitor.Text = Resource.Lang("frmMain", "mStartMonitoring_Stop", "Stop monitoring");
            MainForm.MenuItemStatus.Text = Resource.Lang("frmMain", "mStatus_start", "Starting..");
            MainForm.MenuItemMonitor.Enabled = true;
        }

        internal static void SetSyncingIcon() {
            MainForm.SetTrayIcon(2);
            MainForm.TrayIcon.Text = "Svnbox " + Version + "\n" + Resource.Lang("frmMain", "mStatus_syncing", "Syncing...");
            MainForm.MenuItemStatus.Text = Resource.Lang("frmMain", "mStatus_syncing", "Syncing..");
        }

        public static void OpenWc() {
            try {
                if (Profile.Get("wc", "path") == "")
                    return;
                if (Directory.Exists(Profile.Get("wc", "path")))
                    Process.Start(Profile.Get("wc", "path"));
            } catch { }
        }

        public static void OpenRepo() {
            try {
                if (Profile.Get("svn", "repository") == "")
                    return;
                Process.Start(Profile.Get("svn", "repository"));
            } catch { }
        }
    }
}
